home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 36.9 KB | 1,291 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: FWListBx.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWFrameW.hpp"
-
- #ifndef FWLISTBX_H
- #include "FWListBx.h"
- #endif
-
- #ifndef FWFRAME_H
- #include "FWFrame.h"
- #endif
-
- #ifndef FWCONTXT_H
- #include "FWContxt.h"
- #endif
-
- #ifndef FWWINDOW_H
- #include "FWWindow.h"
- #endif
-
- #ifndef FWEVENT_H
- #include "FWEvent.h"
- #endif
-
- #ifndef FWNOTDEF_H
- #include "FWNotDef.h"
- #endif
-
- #ifndef FWEVEDEF_H
- #include "FWEveDef.h"
- #endif
-
- #ifndef FWITERS_H
- #include "FWIters.h"
- #endif
-
- #ifndef FWRECSHP_H
- #include "FWRecShp.h"
- #endif
-
- #ifndef FWCURSOR_H
- #include "FWCursor.h"
- #endif
-
- #ifndef FWSOMENV_H
- #include "FWSOMEnv.h"
- #endif
-
- #ifndef SLREGION_H
- #include "SLRegion.h"
- #endif
-
- #ifndef SOM_ODFacet_xh
- #include <Facet.xh>
- #endif
-
- //========================================================================================
- // File scope definitions
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment fwgadgts
- #endif
-
- //========================================================================================
- // CLASS FW_CListBox
- //========================================================================================
-
- FW_DEFINE_AUTO(FW_CListBox)
- FW_DEFINE_CLASS_M2(FW_CListBox, FW_CView, FW_MNotifier)
-
- // This class is archivable, but we provide the archiving implementation in a separate
- // translation unit in order to enable deadstripping of the archiving-related code
- // in parts that do not use archiving with this class.
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::FW_CListBox
- //----------------------------------------------------------------------------------------
-
- FW_CListBox::FW_CListBox (Environment* ev,
- FW_CSuperView* container,
- const FW_CRect& bounds,
- ODID id,
- int numRows,
- FW_Boolean scrollVert,
- const FW_CFont& font,
- FW_Message doubleClick,
- FW_Boolean singleSelection,
- FW_Boolean useFocusFrame,
- FW_Boolean useClientData) :
- FW_CView(ev, container, bounds, id),
- #ifdef FW_BUILD_MAC
- fPlatformList(NULL),
- fMacFocusFrame(useFocusFrame),
- fMacFocusFrameOn(FALSE),
- fMacFontID(1),
- fMacFontStyle(0),
- fMacFontSize(12),
- #endif
- fDoubleClickMsg(doubleClick),
- fSingleSelection(singleSelection),
- fUseClientData(useClientData)
- {
- #ifdef FW_BUILD_MAC
- InitMacListBox(ev, bounds, numRows, scrollVert, font);
- #endif
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::FW_CListBox
- //----------------------------------------------------------------------------------------
-
- FW_CListBox::FW_CListBox (Environment* ev) :
- FW_CView(ev),
- #ifdef FW_BUILD_MAC
- fPlatformList(NULL),
- fMacFocusFrame(FALSE),
- fMacFocusFrameOn(FALSE),
- fMacFontID(1),
- fMacFontStyle(0),
- fMacFontSize(12),
- #endif
- fDoubleClickMsg(0),
- fSingleSelection(TRUE),
- fDrawingMode(FALSE),
- fUseClientData(FALSE)
- {
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::~FW_CListBox
- //----------------------------------------------------------------------------------------
-
- FW_CListBox::~FW_CListBox()
- {
- FW_START_DESTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::AdjustCursor
- //----------------------------------------------------------------------------------------
-
- FW_Handled FW_CListBox::AdjustCursor(Environment *ev, ODFacet* odFacet, const FW_CPoint& theMousePoint, ODEventInfo* eventInfo)
- {
- FW_UNUSED(ev);
- FW_UNUSED(odFacet);
- FW_UNUSED(theMousePoint);
- FW_UNUSED(eventInfo);
-
- FW_gArrowCursor.Select();
- return FW_kHandled;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::DoMouseDown
- //----------------------------------------------------------------------------------------
-
- FW_Handled FW_CListBox::DoMouseDown(Environment* ev, const FW_CMouseEvent& theMouseEvent)
- {
-
- #ifdef FW_BUILD_MAC
- // Need a view context to set the correct origin before using the list Manager
- ODFacet* odFacet = theMouseEvent.GetFacet(ev);
- FW_CViewContext gc(ev, this, odFacet);
-
- FW_CPoint canvasWhere = theMouseEvent.GetMousePosition(ev, FW_CMouseEvent::kWindow);
- FW_CPlatformPoint qdWhere = canvasWhere.AsPlatformPoint();
-
- SetupListBox(gc, TRUE, &qdWhere);
-
- if (::LClick(qdWhere, theMouseEvent.GetPlatformModifiers(ev), fPlatformList))
- {
- if (fDoubleClickMsg != 0)
- Notify(ev, FW_CListBoxNotification(this));
- }
-
- #endif
- return FW_kHandled;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::DoActivateEvent
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::DoActivateEvent(Environment *ev, const FW_CActivateEvent& theActivateEvent)
- {
- #ifdef FW_BUILD_MAC
- // Need a view context to set the correct origin before using the list Manager
- FW_CViewContext gc(ev, this, theActivateEvent.GetFacet(ev), NULL);
- SetupListBox(gc);
-
- ::LActivate(theActivateEvent.IsActivating(ev), fPlatformList);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::WantsToBeTarget
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CListBox::WantsToBeTarget(Environment* ev)
- {
- FW_UNUSED(ev);
- // Let visible list views process keys and menu commands
- if (IsVisible(ev))
- return TRUE;
- else
- return FALSE;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::ActivateTarget
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::ActivateTarget (Environment * ev, FW_Boolean tabSelection)
- {
- FW_UNUSED(tabSelection);
-
- #ifdef FW_BUILD_MAC
- if (fMacFocusFrame)
- {
- fMacFocusFrameOn = TRUE;
-
- FW_CViewContext gc(ev, this, GetFrame(ev)->GetActiveFacet(ev), NULL);
- FW_CRect viewRect(FW_kZeroPoint, GetSize(ev));
- FW_CRectShape::RenderRect( gc, viewRect, FW_kFrame,
- FW_kNormalInk, FW_CStyle(FW_IntToFixed(2)));
- }
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::DeactivateTarget
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::DeactivateTarget (Environment * ev)
- {
- #ifdef FW_BUILD_MAC
- if (fMacFocusFrameOn)
- {
- fMacFocusFrameOn = FALSE;
-
- ODFacet* facet = GetFrame(ev)->GetActiveFacet(ev);
- if (facet)
- {
- FW_CViewContext gc(ev, this, facet, NULL);
- FW_CRect viewRect(FW_kZeroPoint, GetSize(ev));
- // [LSD] FW_kWhiteEraseInk won't always be good
- FW_CRectShape::RenderRect( gc, viewRect, FW_kFrame,
- FW_kWhiteEraseInk, FW_CStyle(FW_IntToFixed(2)));
- }
- }
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::SetVisible
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::SetVisible(Environment* ev, FW_Boolean visible, FW_Boolean propagate)
- {
- FW_CView::SetVisible(ev, visible, propagate);
-
- if (visible)
- {
- #ifdef FW_BUILD_MAC
- MacSetVisible(ev, TRUE);
- #endif
- }
- else
- {
- SetDrawingMode(ev, FALSE);
- ResignTarget(ev);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::SetDrawingMode
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CListBox::SetDrawingMode(Environment* ev, FW_Boolean draw)
- {
- FW_UNUSED(ev);
- FW_Boolean oldMode = fDrawingMode;
-
- if (oldMode != draw)
- {
- fDrawingMode = draw;
- #ifdef FW_BUILD_MAC
- ::LSetDrawingMode(draw, fPlatformList);
- #endif
- }
-
- return oldMode;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::Draw
- //----------------------------------------------------------------------------------------
- void FW_CListBox::Draw (Environment* ev, ODFacet* facet, ODShape* invalidShape)
- {
- #ifdef FW_BUILD_MAC
- FW_CViewContext gc(ev, this, facet, invalidShape);
-
- // Use the current port set by FW_CViewContext to allow printing
- GrafPtr savedPort = (*fPlatformList)->port;
- ::GetPort(&((*fPlatformList)->port));
-
- // Convert to grafport coordinates
- FW_CPlatformPoint qdPoint = gc.LogicalToDevice(FW_kZeroPoint);
-
- SetupListBox(gc);
-
- // Compute update region
- FW_CRect invalidRect;
- gc.GetClipRect(invalidRect);
- Rect rgnRect;
- rgnRect.top = FW_FixedToInt(invalidRect.top) + qdPoint.v;
- rgnRect.left = FW_FixedToInt(invalidRect.left) + qdPoint.h;
- rgnRect.bottom = FW_FixedToInt(invalidRect.bottom) + qdPoint.v;
- rgnRect.right = FW_FixedToInt(invalidRect.right) + qdPoint.h;
- RgnHandle updateRgn = ::FW_NewRegion();
- ::RectRgn(updateRgn, &rgnRect);
-
- // Redraw the list box
- ::LUpdate(updateRgn, fPlatformList);
-
- (*fPlatformList)->port = savedPort;
- ::FW_DisposeRegion(updateRgn);
-
- // Draw the frame
- FW_CRect viewRect(FW_kZeroPoint, GetSize(ev));
- FW_CRect listRect(viewRect);
-
- if (fMacFocusFrame)
- {
- listRect.Inset(FW_IntToFixed(3), FW_IntToFixed(3));
-
- if (fMacFocusFrameOn)
- {
- FW_CRectShape::RenderRect( gc, viewRect, FW_kFrame,
- FW_kNormalInk, FW_CStyle(FW_IntToFixed(2)));
- }
- }
- FW_CRectShape::RenderRect(gc, listRect, FW_kFrame, FW_kNormalInk);
-
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::DoVirtualKey
- //----------------------------------------------------------------------------------------
-
- FW_Handled FW_CListBox::DoVirtualKey(Environment* ev, const FW_CVirtualKeyEvent& event)
- {
- #ifdef FW_BUILD_MAC
- // Need a view context to set the correct origin before using the list Manager
- FW_CViewContext gc(ev, this, GetFrame(ev)->GetActiveFacet(ev), NULL);
-
- SetupListBox(gc);
-
- short keyCode = event.GetKeyCode(ev);
- FW_Boolean commandKey = event.IsItemModifier(ev);
- FW_Boolean extendSelection = event.IsExtendModifier(ev) &&
- (((**fPlatformList).selFlags & lOnlyOne) == 0);
- Cell selectCell = {0, 0};
- short viewItem = 1;
-
- switch (keyCode)
- {
- case FW_kVKUp:
- if (::LGetSelect(true, &selectCell, fPlatformList))
- {
- if (commandKey && extendSelection)
- {
- // Select all items above
- while (--selectCell.v >= 0)
- ::LSetSelect(true, selectCell, fPlatformList);
- }
- else if (commandKey)
- {
- // Select top item
- PrivSelectOneItem(ev, 1, TRUE);
- }
- else if (extendSelection)
- {
- // Extend selection above
- if (selectCell.v > 0)
- {
- viewItem = selectCell.v;
- selectCell.v -= 1;
- ::LSetSelect(true, selectCell, fPlatformList);
- }
- }
- else
- {
- // Select 1 item above current one
- if(selectCell.v > 0)
- selectCell.v -= 1;
- viewItem = selectCell.v + 1;
- PrivSelectOneItem(ev, viewItem, TRUE);
- }
- PrivScrollIntoView(viewItem);
- }
- break;
-
- case FW_kVKDown:
- short count;
- short lastItem = PrivGetSelectedItems(&count);
- if (lastItem > 0)
- {
- selectCell.v = lastItem - 1;
- short lastRow = (**fPlatformList).dataBounds.bottom - 1;
-
- if (commandKey && extendSelection)
- {
- while (++selectCell.v <= lastRow)
- ::LSetSelect(true, selectCell, fPlatformList);
- viewItem = lastRow + 1;
- }
- else if (commandKey)
- {
- selectCell.v = lastRow + 1;
- PrivSelectOneItem(ev, selectCell.v, TRUE);
- viewItem = selectCell.v;
- }
- else if (extendSelection) {
- viewItem = lastRow + 1;
- if(selectCell.v < lastRow)
- {
- selectCell.v += 1;
- ::LSetSelect(true, selectCell, fPlatformList);
- viewItem = selectCell.v + 1;
- }
- } else {
- if(selectCell.v < lastRow)
- selectCell.v += 1;
- viewItem = selectCell.v + 1;
- PrivSelectOneItem(ev, viewItem, TRUE);
- }
- PrivScrollIntoView(viewItem);
- }
- break;
-
- case FW_kVKHome:
- ::LScroll(-16000, -16000, fPlatformList);
- break;
-
- case FW_kVKEnd:
- ::LScroll(16000, 16000, fPlatformList);
- break;
-
- case FW_kVKPageUp:
- case FW_kVKPageDown:
- short dRows = (**fPlatformList).visible.bottom - (**fPlatformList).visible.top - 1;
- if (keyCode == FW_kVKPageUp)
- dRows = -dRows;
- ::LScroll(0, dRows, fPlatformList);
- break;
-
- default:
- return FW_kNotHandled;
- }
-
- return FW_kHandled;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::Flatten
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::Flatten(Environment* ev, FW_CWritableStream& stream) const
- {
- FW_CView::Flatten(ev, stream);
-
- short numRows = GetCountItems(ev);
- FW_Boolean scrollVert = ((**fPlatformList).vScroll != 0);
-
- stream << numRows;
- stream << scrollVert;
- stream << fSingleSelection;
- stream << fMacFocusFrame;
- stream << fUseClientData;
- stream << fDoubleClickMsg;
- stream << FW_CFont(FW_kNormalFont); // [LSD] use default value for now
-
- stream << numRows;
- FW_CString str;
- for (int i = 1; i <= numRows; i++)
- {
- GetStringItem(ev, i, str);
- stream << str;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::InitializeFromStream
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::InitializeFromStream(Environment* ev, FW_CReadableStream& stream)
- {
- FW_CView::InitializeFromStream(ev, stream);
-
- short numRows;
- FW_Boolean scrollVert;
- FW_CFont font;
-
- stream >> numRows;
- stream >> scrollVert;
- stream >> fSingleSelection;
- stream >> fMacFocusFrame;
- stream >> fUseClientData;
- stream >> fDoubleClickMsg;
- stream >> font;
-
- InitMacListBox(ev, GetBounds(ev), numRows, scrollVert, font);
-
- // ----- Read string items
- SetDrawingMode(ev, FALSE);
-
- short numStrings;
- stream >> numStrings;
-
- if (numStrings > numRows)
- numStrings = numRows;
-
- FW_CString str;
- for (int i = 1; i <= numStrings; i++)
- {
- stream >> str;
- SetStringItem(ev, i, str);
- }
-
- SetDrawingMode(ev, TRUE);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::SizeChanged
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::SizeChanged(Environment* ev, const FW_CPoint& oldSize)
- {
- FW_CView::SizeChanged(ev, oldSize);
-
- #ifdef FW_BUILD_MAC
- // The list manager redraws and validates list scrollbars when a list
- // is resized whether or not drawing is on. It also validates the
- // space where a horizontal scrollbar would be whether or not there is a
- // horizontal scrollbar. To prevent redraw and validation while resizing,
- // we set the clip region of the grafport that contains the list to NULL
- // while we are sizing. This also lets us postpone the manipulations we
- // do to align lists on 8 byte boundaries until a time when we have
- // a view context.
-
- RgnHandle savedClip = (*fPlatformList)->port->clipRgn;
- (*fPlatformList)->port->clipRgn = NewRgn();
-
- FW_CPoint size = GetSize(ev);
- FW_Fixed vInset = FW_IntToFixed(2 * (fMacFocusFrame ? 4 : 1));
- FW_Fixed hInset(vInset);
-
- if ((*fPlatformList)->vScroll != NULL)
- hInset += FW_IntToFixed(15);
-
- size -= FW_CPoint(hInset, vInset);
-
- LSize(size.IntX(), size.IntY(), fPlatformList);
-
- // Adjust the cell width. The cell height will already be correct for the
- // font, and shouldn't be adjusted.
- FW_PlatformPoint cellSize = (*fPlatformList)->cellSize;
- cellSize.h = size.IntX();
- LCellSize(cellSize, fPlatformList);
-
- DisposeRgn((*fPlatformList)->port->clipRgn);
- (*fPlatformList)->port->clipRgn = savedClip;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::GetCountItems
- //----------------------------------------------------------------------------------------
-
- short FW_CListBox::GetCountItems(Environment* ev) const
- {
- FW_UNUSED(ev);
- // return number of rows
- #ifdef FW_BUILD_MAC
- return (**fPlatformList).dataBounds.bottom;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::GetSelectionCount
- //----------------------------------------------------------------------------------------
-
- short FW_CListBox::GetSelectionCount(Environment* ev) const
- {
- FW_UNUSED(ev);
- #ifdef FW_BUILD_MAC
- short count;
- PrivGetSelectedItems(&count);
- return count;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::GetSelectedState
- //----------------------------------------------------------------------------------------
- // return if an item is selected
-
- FW_Boolean FW_CListBox::GetSelectedState(Environment* ev, short index) const
- {
- if (!CheckIndex(ev, index)) return FALSE;
-
- #ifdef FW_BUILD_MAC
- Cell curSel = {index - 1, 0};
-
- if (::LGetSelect(false, &curSel, fPlatformList))
- return TRUE;
- else
- return FALSE;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::GetSelectedItem
- //----------------------------------------------------------------------------------------
- // find the first selected item
-
- short FW_CListBox::GetSelectedItem(Environment* ev) const
- {
- FW_UNUSED(ev);
- #ifdef FW_BUILD_MAC
- Cell curSel = {0, 0};
- if (::LGetSelect(true, &curSel, fPlatformList))
- return curSel.v + 1;
- else
- return 0; // no item selected
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::GetSelectedItems
- //----------------------------------------------------------------------------------------
- // build an array of selected items, return the number of items read
-
- short FW_CListBox::GetSelectedItems(Environment* ev, short maxItems, short* indexArray) const
- {
- FW_UNUSED(ev);
- FW_ASSERT(!fSingleSelection); // only multi-selection list boxes allowed
-
- #ifdef FW_BUILD_MAC
- short count;
- PrivGetSelectedItems(&count, maxItems, indexArray);
- return count;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::GetStringItem
- //----------------------------------------------------------------------------------------
- // read the 255 chars value of an item. Return FALSE if no data was read
-
- FW_Boolean FW_CListBox::GetStringItem(Environment* ev, short index, FW_CString& str) const
- {
- if (!CheckIndex(ev, index)) return FALSE;
-
- #ifdef FW_BUILD_MAC
- Cell itemCell = {index - 1, 0};
- char pStr[255];
- short dataLen = 255;
-
- ::LGetCell(pStr, &dataLen, itemCell, fPlatformList);
-
- if (dataLen > 0)
- str.ReplaceAll(pStr, (FW_ByteCount)dataLen);
-
- return (dataLen > 0);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::GetStringItem
- //----------------------------------------------------------------------------------------
- // read the 255 chars value of an item + the 4 bytes value associated.
- // return FALSE if the 4 bytes data was not found.
-
- FW_Boolean FW_CListBox::GetStringItem(Environment* ev, short index, FW_CString& str,
- void** clientData) const
- {
- FW_ASSERT(fUseClientData);
- if (!CheckIndex(ev, index)) return FALSE;
-
- GetStringItem(ev, index, str);
-
- #ifdef FW_BUILD_MAC
- Cell itemCell = {index - 1, 1};
- short dataLen = 4;
-
- ::LGetCell(clientData, &dataLen, itemCell, fPlatformList);
-
- return (dataLen == 4);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::GetClientDataItem
- //----------------------------------------------------------------------------------------
- // read the 4 bytes value stored in 2nd column. Return FALSE if couldn't read 4 bytes
-
- FW_Boolean FW_CListBox::GetClientDataItem(Environment* ev, short index, void** clientData) const
- {
- FW_ASSERT(fUseClientData);
- if (!CheckIndex(ev, index)) return FALSE;
-
- #ifdef FW_BUILD_MAC
- Cell itemCell = {index - 1, 1};
- short dataLen = 4;
-
- ::LGetCell(clientData, &dataLen, itemCell, fPlatformList);
-
- return (dataLen == 4);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::SetStringItem
- //----------------------------------------------------------------------------------------
- // Set the string value of an existing item
-
- void FW_CListBox::SetStringItem(Environment* ev, short index, const FW_CString& str)
- {
- if (!CheckIndex(ev, index)) return; // index out of range (item doesn't exist)
-
- if (fDrawingMode)
- {
- // Must setup the listbox to be sure it's drawn correctly
- // Must also loop on all facets for this frame
- FW_CFrameFacetIterator ite(ev, GetFrame(ev));
- for (ODFacet* facet = ite.First(ev); ite.IsNotComplete(ev); facet = ite.Next(ev))
- {
- FW_CViewContext vc(ev, this, facet);
- SetupListBox(vc);
-
- MacSetItem(index, str);
- }
- }
- else
- MacSetItem(index, str);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::SetStringItem
- //----------------------------------------------------------------------------------------
- // Set the string value of an existing item + set its 4 bytes clientData
-
- void FW_CListBox::SetStringItem(Environment* ev, short index, const FW_CString& str,
- void* clientData)
- {
- FW_ASSERT(fUseClientData);
- if (!CheckIndex(ev, index)) return; // index out of range (item doesn't exist)
-
- if (fDrawingMode)
- {
- // Must setup the listbox to be sure it's drawn correctly
- // Must also loop on all facets for this frame
- FW_CFrameFacetIterator ite(ev, GetFrame(ev));
- for (ODFacet* facet = ite.First(ev); ite.IsNotComplete(ev); facet = ite.Next(ev))
- {
- FW_CViewContext vc(ev, this, facet);
- SetupListBox(vc);
-
- MacSetItem(index, str, TRUE, clientData);
- }
- }
- else
- MacSetItem(index, str, TRUE, clientData);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::AddStringItem
- //----------------------------------------------------------------------------------------
- // Add a new item to the list and sets its string value
- // if index = 0, item is added at the end of the list
-
- void FW_CListBox::AddStringItem(Environment* ev, const FW_CString& str, short index)
- {
- FW_ASSERT(index >= 0);
-
- short count = GetCountItems(ev);
- if (index == 0 || index > count)
- index = count + 1;
-
- if (fDrawingMode)
- {
- // Must setup the listbox to be sure it's drawn correctly
- // Must also loop on all facets for this frame
- FW_CFrameFacetIterator ite(ev, GetFrame(ev));
- for (ODFacet* facet = ite.First(ev); ite.IsNotComplete(ev); facet = ite.Next(ev))
- {
- FW_CViewContext vc(ev, this, facet);
- SetupListBox(vc);
-
- #ifdef FW_BUILD_MAC
- ::LAddRow(1, index-1, fPlatformList);
- MacSetItem(index, str);
- #endif
- }
- }
- else
- {
- #ifdef FW_BUILD_MAC
- ::LAddRow(1, index-1, fPlatformList);
- MacSetItem(index, str);
- #endif
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::AddStringItem
- //----------------------------------------------------------------------------------------
- // Add a new item to the list and sets its string value
- // if index = 0, item is added at the end of the list
-
- void FW_CListBox::AddStringItem(Environment* ev, const FW_CString& str, void* clientData,
- short index)
- {
- FW_ASSERT(index >= 0);
- FW_ASSERT(fUseClientData);
- if (index < 0 || index > 16000) return;
-
- short count = GetCountItems(ev);
- if (index == 0 || index > count)
- index = count + 1;
-
- if (fDrawingMode)
- {
- // Must setup the listbox to be sure it's drawn correctly
- // Must also loop on all facets for this frame
- FW_CFrameFacetIterator ite(ev, GetFrame(ev));
- for (ODFacet* facet = ite.First(ev); ite.IsNotComplete(ev); facet = ite.Next(ev))
- {
- FW_CViewContext vc(ev, this, facet);
- SetupListBox(vc);
-
- #ifdef FW_BUILD_MAC
- ::LAddRow(1, index-1, fPlatformList);
- MacSetItem(index, str, TRUE, clientData);
- #endif
- }
- }
- else
- {
- #ifdef FW_BUILD_MAC
- ::LAddRow(1, index-1, fPlatformList);
- MacSetItem(index, str, TRUE, clientData);
- #endif
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::DeleteItems
- //----------------------------------------------------------------------------------------
- // Delete "count" rows starting at "index"
-
- void FW_CListBox::DeleteItems(Environment* ev, short index, short count)
- {
- if (count <= 0 || !CheckIndex(ev, index)) return;
-
- #ifdef FW_BUILD_MAC
- if (fDrawingMode)
- {
- // Must setup the listbox to be sure it's drawn correctly
- // Must also loop on all facets for this frame
- FW_CFrameFacetIterator ite(ev, GetFrame(ev));
- for (ODFacet* facet = ite.First(ev); ite.IsNotComplete(ev); facet = ite.Next(ev))
- {
- FW_CViewContext vc(ev, this, facet);
- SetupListBox(vc);
-
- ::LDelRow(count, index-1, fPlatformList);
- }
- }
- else
- {
- ::LDelRow(count, index-1, fPlatformList);
- }
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::PrivSelectOneItem
- //----------------------------------------------------------------------------------------
- // Internal use only. ViewContext must be setup already.
-
- void FW_CListBox::PrivSelectOneItem(Environment* ev, short index, FW_Boolean selected)
- {
- FW_UNUSED(ev);
- #ifdef FW_BUILD_MAC
- Cell curCell = {0, 0};
- Cell itemCell = {index - 1, 0};
-
- // Follows recipe from Inside Mac "More ToolBox" page 4-36 to select without
- // flashing
- if (selected && fDrawingMode)
- {
- while (::LGetSelect(TRUE, &curCell, fPlatformList))
- {
- if (*(long*)&curCell == *(long*)&itemCell)
- ::LNextCell(FALSE, TRUE, &curCell, fPlatformList);
- else
- ::LSetSelect(FALSE, curCell, fPlatformList);
- }
- }
-
- ::LSetSelect(selected ? TRUE : FALSE, itemCell, fPlatformList);
- #endif
-
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::SelectOneItem
- //----------------------------------------------------------------------------------------
- // Set the selection state of 1 item, On or Off
-
- void FW_CListBox::SelectOneItem(Environment* ev, short index, FW_Boolean selected)
- {
- if (!CheckIndex(ev, index)) return;
-
- if (fDrawingMode)
- {
- // Must setup the listbox to be sure it's drawn correctly
- // Must also loop on all facets for this frame
- FW_CFrameFacetIterator ite(ev, GetFrame(ev));
- for (ODFacet* facet = ite.First(ev); ite.IsNotComplete(ev); facet = ite.Next(ev))
- {
- FW_CViewContext vc(ev, this, facet);
- SetupListBox(vc);
-
- PrivSelectOneItem(ev, index, selected);
- }
- }
- else
- {
- PrivSelectOneItem(ev, index, selected);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::PrivScrollIntoView
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::PrivScrollIntoView(short index)
- {
-
- #ifdef FW_BUILD_MAC
- Rect visibleCells = (**fPlatformList).visible;
- Cell itemCell = {index - 1, 0};
-
- // recipe from Inside Mac "More ToolBox" page 4-37
- if (::PtInRect(itemCell, &visibleCells) == FALSE)
- {
- short dRows = 0;
- if (itemCell.v > visibleCells.bottom - 1)
- dRows = itemCell.v - visibleCells.bottom + 1;
- else if (itemCell.v < visibleCells.top)
- dRows = itemCell.v - visibleCells.top;
-
- ::LScroll(0, dRows, fPlatformList);
- visibleCells = (**fPlatformList).visible;
- }
-
- // if item is at the bottom check that it is entirely visible
- short numVisibleCells = visibleCells.bottom - visibleCells.top;
- if (itemCell.v == visibleCells.bottom - 1 && numVisibleCells > 1)
- {
- short visibleHeight = numVisibleCells * (**fPlatformList).cellSize.v;
- Rect listRect = (**fPlatformList).rView;
-
- if (visibleHeight > (listRect.bottom - listRect.top))
- ::LScroll(0, 1, fPlatformList);
- }
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::ScrollIntoView
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::ScrollIntoView(Environment* ev, short index)
- {
- short count = GetCountItems(ev);
- if (index <= 0 || index > count)
- index = count + 1;
-
- // Must setup the listbox to be sure it's drawn correctly
- // Must also loop on all facets for this frame
- FW_CFrameFacetIterator ite(ev, GetFrame(ev));
- for (ODFacet* facet = ite.First(ev); ite.IsNotComplete(ev); facet = ite.Next(ev))
- {
- FW_CViewContext vc(ev, this, facet);
- SetupListBox(vc);
-
- PrivScrollIntoView(index);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::CheckIndex
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CListBox::CheckIndex(Environment* ev, short index) const
- {
- if (index <= 0 || index > GetCountItems(ev))
- {
- FW_DEBUG_MESSAGE("Wrong index for FW_CListBox");
- return FALSE;
- }
- return TRUE;
- }
-
-
- //========================================================================================
- // Macintosh specific code below
- #ifdef FW_BUILD_MAC
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::PrivGetSelectedItems
- //----------------------------------------------------------------------------------------
- // If maxItems = 0, count the number of selected items and return the index of the last one
- // If maxItems > 0, store indexes in an array and count only the number found (<= maxItems)
-
- short FW_CListBox::PrivGetSelectedItems(short* count, short maxItems, short* indexArray) const
- {
- Cell curItem = {0, 0};
- short i = 0;
- short index = 0;
-
- // Follows recipe from Inside Mac "More ToolBox" page 4-35
- if (::LGetSelect(TRUE, &curItem, fPlatformList))
- {
- do
- {
- index = curItem.v + 1;
- i++;
- if (maxItems > 0)
- {
- if (indexArray)
- indexArray[i-1] = index;
- if (i == maxItems)
- break;
- }
- } while (::LNextCell(FALSE, TRUE, &curItem, fPlatformList) &&
- ::LGetSelect(TRUE, &curItem, fPlatformList));
- }
- *count = i;
- return index;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::InitMacListBox
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::InitMacListBox(Environment* ev,
- const FW_CRect& bounds,
- int numRows,
- FW_Boolean scrollVert,
- const FW_CFont& font)
- {
- Rect listRect;
-
- // list box rect doesn't contain border and scroll-bars
- int border = fMacFocusFrame ? 4 : 1;
-
- listRect.left = FW_FixedToInt(bounds.left) + border;
- listRect.top = FW_FixedToInt(bounds.top) + border;
- listRect.right = FW_FixedToInt(bounds.right) - border;
- listRect.bottom = FW_FixedToInt(bounds.bottom) - border;
-
- if (scrollVert)
- listRect.right -= 15;
-
- // Set the font to be used to draw cells in this window
- FW_CAcquiredODWindow aqODWindow = GetFrame(ev)->GetWindow(ev)->AcquireODWindow(ev);
- GrafPtr macPort = aqODWindow->GetPlatformWindow(ev);
- GrafPtr oldPort;
- ::GetPort(&oldPort);
- ::SetPort(macPort);
-
- fMacFontID = font.MacGetFontID();
- fMacFontStyle = font.MacGetFontStyle();
- fMacFontSize = FW_FixedToInt(font.GetFontSize());
- ::TextFont(fMacFontID);
- ::TextFace(fMacFontStyle);
- ::TextSize(fMacFontSize);
- ::TextMode(srcOr);
-
- // Use 2 columns for storing clientdata items
- Rect dataBounds = {0, 0, numRows, (fUseClientData ? 2 : 1)};
-
- // Adjust cell width. Cell height will be set according to the font
- Point cellSize = { 0, listRect.right - listRect.left};
-
- // Create the Mac list box handle
- fPlatformList = ::LNew(&listRect, &dataBounds, cellSize,
- 0, // use default LDEF
- macPort, // port window
- false, // don't draw it
- false, // no Grow box space
- false, // no Horizontal scrollbar
- scrollVert);
-
- if (fSingleSelection)
- (**fPlatformList).selFlags |= lOnlyOne;
-
- MacSetVisible(ev, true);
-
- if (oldPort != macPort)
- ::SetPort(oldPort);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::MacSetVisible
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::MacSetVisible(Environment* ev, FW_Boolean activate)
- {
- // Turn on drawing mode & set activation
- // but avoid immediate redraw by clipping to empty rect
- GrafPtr oldPort;
- ::GetPort(&oldPort);
- ::SetPort((**fPlatformList).port);
- RgnHandle clipRgn = ::FW_NewRegion();
- if (clipRgn)
- {
- ::GetClip(clipRgn);
- Rect emptyRect = {0, 0, 0, 0};
- ::ClipRect(&emptyRect);
- }
-
- SetDrawingMode(ev, TRUE);
-
- ::LActivate(activate, fPlatformList);
-
- if (clipRgn)
- {
- ::SetClip(clipRgn);
- ::FW_DisposeRegion(clipRgn);
- }
- ::SetPort(oldPort);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::MacSetItem
- //----------------------------------------------------------------------------------------
-
- void FW_CListBox::MacSetItem(short index, const FW_CString& str, FW_Boolean hasClientData,
- void* clientData)
- {
- Cell itemCell = {index - 1, 0};
-
- FW_PascalChar pStr[255];
- str.ExportPascal(pStr);
-
- ::LSetCell(pStr+1, pStr[0], itemCell, fPlatformList);
-
- if (hasClientData && fUseClientData)
- {
- // Set clientdata value in second (invisible) column
- itemCell.h = 1;
- ::LSetCell(&clientData, 4, itemCell, fPlatformList);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBox::SetupListBox
- //----------------------------------------------------------------------------------------
- // SetupListBox must be called before any List Manager call that may redraw the list box
- // (and after creating a View Context which will set the correct port) in order to
- // adjust the listbox and scrollbars rects and set the fonts.
-
- void FW_CListBox::SetupListBox(FW_CViewContext& vc,
- FW_Boolean mouseDownEvent,
- FW_CPlatformPoint* qdWhere)
- {
- Rect curRect = (**fPlatformList).rView;
-
- FW_CPlatformPoint qdPoint = vc.LogicalToDevice(FW_kZeroPoint);
-
- short border = fMacFocusFrame ? 4 : 1;
- short hDelta = qdPoint.h - curRect.left + border;
- short vDelta = qdPoint.v - curRect.top + border;
- if (hDelta != 0 || vDelta != 0)
- {
- ::OffsetRect(&(**fPlatformList).rView, hDelta, vDelta);
- if ((**fPlatformList).vScroll)
- ::OffsetRect(&(**((**fPlatformList).vScroll)).contrlRect, hDelta, vDelta);
- if ((**fPlatformList).hScroll)
- ::OffsetRect(&(**((**fPlatformList).hScroll)).contrlRect, hDelta, vDelta);
- }
-
- if (mouseDownEvent)
- {
- // We must adjust the mouse position by the offset created by the view
- // context (to handle pattern alignment). See also FW_CControl::DoMouseDown
- ODPlatformCanvas plfmCanvas = vc.GetPlatformCanvas();
- qdWhere->h += plfmCanvas->portRect.left;
- qdWhere->v += plfmCanvas->portRect.top;
- }
-
- // Setup the correct font (port has been set by the ViewContext)
- ::TextFont(fMacFontID);
- ::TextFace(fMacFontStyle);
- ::TextSize(fMacFontSize);
- }
-
- //========================================================================================
- // CLASS FW_CListBoxNotification
- //========================================================================================
-
- FW_DEFINE_CLASS_M1(FW_CListBoxNotification, FW_CNotification)
-
- //----------------------------------------------------------------------------------------
- // FW_CListBoxNotification::FW_CListBoxNotification
- //----------------------------------------------------------------------------------------
-
- FW_CListBoxNotification::FW_CListBoxNotification(FW_CListBox* listbox) :
- FW_CNotification(),
- fListBox(listbox)
- {
- FW_SOMEnvironment ev;
- FW_Message msg = listbox->GetDoubleClickedMsg(ev);
- SetInterest(FW_CInterest((FW_MNotifier*)listbox, msg));
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBoxNotification::FW_CListBoxNotification
- //----------------------------------------------------------------------------------------
-
- FW_CListBoxNotification::FW_CListBoxNotification(const FW_CListBoxNotification& other) :
- FW_CNotification(other),
- fListBox(other.fListBox)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBoxNotification::~FW_CListBoxNotification
- //----------------------------------------------------------------------------------------
-
- FW_CListBoxNotification::~FW_CListBoxNotification()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBoxNotification::operator=
- //----------------------------------------------------------------------------------------
-
- FW_CListBoxNotification& FW_CListBoxNotification::operator=(const FW_CListBoxNotification& other)
- {
- if (this != &other)
- {
- FW_CNotification::operator=(other);
- fListBox = other.fListBox;
- }
-
- return *this;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CListBoxNotification::operator==
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CListBoxNotification::operator==(const FW_CListBoxNotification& other) const
- {
- return FW_CNotification::operator==(other) && fListBox == other.fListBox;
- }
-
- #endif
-
-
-